package crawl

import (
	"net"
	"net/http"
	"net/url"
	"time"
)

type (
	ClientOption     interface{ Apply(client *http.Client) }
	ClientOptions    []ClientOption
	ClientOptionFunc func(client *http.Client)
	ProxyFunc        func(*http.Request) (*url.URL, error)
)

func (opts ClientOptions) Apply(client *http.Client) {
	for _, opt := range opts {
		opt.Apply(client)
	}
}

func (fn ClientOptionFunc) Apply(client *http.Client) {
	if fn != nil {
		fn(client)
	}
}

//Proxy 设置代理
func Proxy(proxy ProxyFunc) ClientOption {
	if proxy == nil {
		proxy = http.ProxyFromEnvironment
	}
	return ClientOptionFunc(func(client *http.Client) {
		if client.Transport == nil {
			client.Transport = &http.Transport{
				Proxy:                 proxy,
				DialContext:           (&net.Dialer{Timeout: 30 * time.Second, KeepAlive: 30 * time.Second}).DialContext,
				ForceAttemptHTTP2:     true,
				MaxIdleConns:          100,
				IdleConnTimeout:       90 * time.Second,
				TLSHandshakeTimeout:   10 * time.Second,
				ExpectContinueTimeout: 1 * time.Second,
			}
		} else {
			if httpTransport, ok := client.Transport.(*http.Transport); ok {
				httpTransport.Proxy = proxy
			}
		}
	})
}
